iT邦幫忙

2

[Day20]番茄鐘(Pomodoro)GUI

  • 分享至 

  • xImage
  •  

今天用 Python+Tkinter 做一個番茄鐘:專注 N 分鐘 → 休息 M 分鐘,支援開始/暫停/重置,完成會響鈴提醒。預設 25/5 分鐘,可自行調整。

功能重點

  • 專注與休息時間可調整
  • 開始、暫停、重置
  • 每完成一輪會嗶一聲並自動切換
  • 計數今天完成幾次番茄
  • 按下 Enter 也能開始
  • Tkinter 為標準庫(Windows、macOS 內建)。部分 Linux 需安裝 python3-tk。

程式碼(存成 pomodoro.py

import tkinter as tk
from tkinter import ttk, messagebox

# --- 狀態 ---
running = False
mode = "work"      # "work" or "break"
remaining = 0
rounds = 0
tick_job = None

def fmt(sec: int) -> str:
    m, s = divmod(max(0, sec), 60)
    return f"{m:02d}:{s:02d}"

def set_mode(new_mode: str):
    global mode, remaining
    mode = new_mode
    try:
        w = int(work_min.get())
        b = int(break_min.get())
        if w <= 0 or b <= 0:
            raise ValueError
    except ValueError:
        messagebox.showerror("輸入錯誤", "請填入大於 0 的整數分鐘")
        return
    remaining = (w if mode == "work" else b) * 60
    status_var.set("專注中" if mode == "work" else "休息中")
    time_var.set(fmt(remaining))

def start():
    global running
    if running: return
    running = True
    tick()

def pause():
    global running, tick_job
    running = False
    if tick_job:
        root.after_cancel(tick_job)

def reset():
    global running, rounds
    pause()
    rounds = 0
    rounds_var.set("本日完成:0 次番茄")
    set_mode("work")

def tick():
    global remaining, rounds, tick_job
    if not running: return
    remaining -= 1
    time_var.set(fmt(remaining))
    if remaining <= 0:
        root.bell()  # 提示音
        if mode == "work":
            rounds += 1
            rounds_var.set(f"本日完成:{rounds} 次番茄")
            set_mode("break")
        else:
            set_mode("work")
    tick_job = root.after(1000, tick)

# --- 介面 ---
root = tk.Tk()
root.title("Pomodoro 番茄鐘")

main = ttk.Frame(root, padding=16); main.grid()

status_var = tk.StringVar(value="專注中")
time_var = tk.StringVar(value="25:00")
rounds_var = tk.StringVar(value="本日完成:0 次番茄")

ttk.Label(main, textvariable=status_var, font=("Segoe UI", 12)).grid(row=0, column=0, columnspan=3, pady=(0,6))
ttk.Label(main, textvariable=time_var, font=("Segoe UI", 36)).grid(row=1, column=0, columnspan=3, pady=6)

# 設定
work_min = tk.StringVar(value="25")
break_min = tk.StringVar(value="5")
ttk.Label(main, text="專注(分)").grid(row=2, column=0, sticky="e", pady=4)
ttk.Entry(main, textvariable=work_min, width=6, justify="center").grid(row=2, column=1, sticky="w")
ttk.Label(main, text="休息(分)").grid(row=3, column=0, sticky="e", pady=4)
ttk.Entry(main, textvariable=break_min, width=6, justify="center").grid(row=3, column=1, sticky="w")

btns = ttk.Frame(main); btns.grid(row=4, column=0, columnspan=3, pady=10)
ttk.Button(btns, text="開始", command=start).grid(row=0, column=0, padx=4)
ttk.Button(btns, text="暫停", command=pause).grid(row=0, column=1, padx=4)
ttk.Button(btns, text="重置", command=reset).grid(row=0, column=2, padx=4)

ttk.Label(main, textvariable=rounds_var).grid(row=5, column=0, columnspan=3)

# 初始
set_mode("work")
root.bind("<Return>", lambda e: start())
root.mainloop()

使用方式

python pomodoro.py

實作:
https://ithelp.ithome.com.tw/upload/images/20251008/20169368Py66RRLWQC.png
小提醒
想改成 50/10?介面上把「專注(分)」改 50、「休息(分)」改 10,按「重置」後再「開始」。


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言